package com.ylz.sjzx.sio.common.core.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author wiqi
 * @version 1.0
 * @date 2020/11/23
 */
@Slf4j
@Component
public class GsonUtil {
    private static Gson gson = new GsonBuilder().create();

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 通过该方法对mapper对象进行设置，所有序列化的对象都将按改规则进行系列化
        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空（""） 或者为 NULL 都不序列化，则返回的json是没有这个字段的。这样对移动端会更省流量
        // Include.NON_NULL 属性为NULL 不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许出现单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addDeserializer(LocalDateTime.class,
                new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));

        objectMapper.registerModule(javaTimeModule);
    }

    public static String bean2Json(Object obj) {
        Class<?> aClass = obj.getClass();
        if (DeclareFieldUtil.isStandardProperty(aClass)) {
            return obj.toString();
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转str失败{}", obj, e);

        }
        return null;
    }

    public static <T> T json22Bean(String jsonStr, Class<T> objClass) {
        if (StrUtil.isBlank(jsonStr)) {
            return null;
        }
        if (Objects.equals(objClass, String.class)) {
            return (T) jsonStr;
        }
        try {
            return objectMapper.readValue(jsonStr, objClass);
        } catch (Exception e) {
            log.error("转对象失败{}", jsonStr, e);
        }
        return null;
    }

    public static <T> T json2Bean(Object jsonStr, Class<T> objClass) {
        if (jsonStr == null) {
            return null;
        }
        return json22Bean(jsonStr.toString(), objClass);
    }

    public static <T> List<T> json2BeanList(List<String> listStr, Class<T> objClass) {
        if (CollectionUtil.isEmpty(listStr)) {
            return null;
        }
        return listStr.stream().map(item -> GsonUtil.json2Bean(item, objClass)).collect(Collectors.toList());
    }

}
